package com.boarsoft.boar.config.var.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.boar.app.AppInstBiz;
import com.boarsoft.boar.config.entity.ConfigVar;
import com.boarsoft.boar.config.entity.ConfigVarApp;
import com.boarsoft.boar.config.entity.ConfigVarEnv;
import com.boarsoft.boar.config.var.ConfigVarAppBiz;
import com.boarsoft.boar.config.var.ConfigVarBiz;
import com.boarsoft.boar.config.var.ConfigVarEnvBiz;
import com.boarsoft.boar.config.var.ConfigVarProcessor;
import com.boarsoft.boar.entity.AppInfo;
import com.boarsoft.boar.entity.AppInst;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.config.core.ConfigVarSync;
import com.boarsoft.rpc.core.RpcContext;

public class LocalConfigVarProcessor implements ConfigVarProcessor {

	@Autowired
	protected AppInstBiz appInstBiz;
	@Autowired
	protected ConfigVarBiz configVarBiz;
	@Autowired
	protected ConfigVarEnvBiz configVarEnvBiz;
	@Autowired
	protected ConfigVarAppBiz configVarAppBiz;
	@Autowired
	protected ConfigVarSync configVarSync;

	
	@Override
	public ConfigVar get(String appId, String env, String name) {

		return null;
	}

	@Override
	public List<ConfigVar> list(String appId, String env,String group) {
		return null;
	}

	@Override public PagedResult<ConfigVar> page(String projId, String env, String key, int pageNo, int pageSize,
			String orderBy) {
		return null;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED,rollbackFor = {Exception.class})
	public void save(ConfigVar cv) {
		if (Util.strIsEmpty(cv.getId())) {
			String varId=configVarBiz.add(cv);
			ConfigVarApp app=new ConfigVarApp();
			app.setVarId(varId);
			app.setAppId(cv.getAppId());
			configVarAppBiz.save(app);
			if (cv.getEnv() != null) {
				ConfigVarEnv configVarEnv = new ConfigVarEnv();
				configVarEnv.setEnv(cv.getEnv());
				configVarEnv.setValue(cv.getValue());
				configVarEnv.setVarId(varId);
				configVarEnvBiz.add(configVarEnv);
			}
		} else {
			this.update(cv);
		}
	}

	@Override
	public void update(ConfigVar cv) {
		ConfigVar a = configVarBiz.get(cv.getId());
		a.setGroup(cv.getGroup());
		a.setName(cv.getName());
		a.setValue(cv.getValue());
		a.setMemo(cv.getMemo());
		a.setVer(cv.getVer());
		a.setStatus(cv.getStatus());
		if (cv.getEnv() != null) {
			ConfigVarEnv configVarEnv = configVarEnvBiz.find(cv.getId(), cv.getEnv());
			configVarEnv.setValue(cv.getValue());
			configVarEnvBiz.update(configVarEnv);
			cv.setValue("");
		}
		configVarBiz.update(a);
	}

	@Override
	public void delete(ConfigVar cv) {
		if(cv.getId()!=null){
			configVarBiz.delete(cv.getId());
		}
		ConfigVar o = configVarBiz.findByName(cv.getAppId(), cv.getName(), cv.getVer());
		List<AppInfo> appLt = configVarAppBiz.list(o.getId());
		Map<String, String> rm = new HashMap<>();
		for (AppInfo a : appLt) {
			List<AppInst> instLt = appInstBiz.list(//
					null, a.getId(), null, AppInst.STATUS_RUNNING);
			for (AppInst i : instLt) {
				RpcContext.specify2(i.getAddr());
				try {
					configVarSync.delete(o.getGroup(), o.getName());
					rm.put(i.getAddr(), "success");
				} catch (Exception e) {
					rm.put(i.getAddr(), e.getMessage());
				} finally {
					RpcContext.specify2(null);
				}
			}
		}
		configVarBiz.delete(o.getId());
		for(ConfigVarEnv cve:configVarEnvBiz.list(cv.getId())){
			configVarEnvBiz.delete(cve.getId());
		}
	}

	@Override
	public void delete(String id) {
		ConfigVar o = configVarBiz.get(id);
		delete(o);
	}

	@Override
	public void put(ConfigVar cv) {
		// 查询当前变量关联的应用
		List<AppInfo> appLt = configVarAppBiz.list(cv.getId());
		Map<String, String> pm = new HashMap<>();
		pm.put(cv.getName(), cv.getValue());
		Map<String, String> rm = new HashMap<>();
		for (AppInfo a : appLt) {
			List<AppInst> instLt = appInstBiz.list(//
					null, a.getId(), null, AppInst.STATUS_RUNNING);
			for (AppInst i : instLt) {
				RpcContext.specify2(i.getAddr());
				try {
					configVarSync.put(cv.getGroup(), pm);
					rm.put(i.getAddr(), "success");
				} catch (Exception e) {
					rm.put(i.getAddr(), e.getMessage());
				} finally {
					RpcContext.specify2(null);
				}
			}
		}
	}
}
